`timescale 1ns/1ps
`default_nettype none
// -----------------------------------------------------------------------------
// controller.v  —— 译码产生控制信号（ADDI/ADD/SUB/LW/SW）
// -----------------------------------------------------------------------------
module controller(
    input  wire [31:0] instr,
    output wire        regwrite,   // 是否写回寄存器堆（给 WB）
    output wire        alusrc,     // 1=使用立即数(B=imm)，0=使用rs2
    output wire [3:0]  alu_ctrl,   // ALU 功能码：0000=ADD ;0001=SUB
    output wire        memread,    // 是否从 dmem 读（LW）
    output wire        memwrite,   // 是否写 dmem（SW）
    output wire        memtoreg    // 写回选择：1=mem_rdata，0=alu_y
);
    wire [6:0] opcode = instr[6:0];
    wire [2:0] funct3 = instr[14:12];
    wire [6:0] funct7 = instr[31:25];

    // I-type: ADDI
    wire is_addi = (opcode == 7'b0010011) && (funct3 == 3'b000);

    // R-type: ADD/SUB (funct3=000)
    wire is_rtype = (opcode == 7'b0110011) && (funct3 == 3'b000);
    wire is_add   = is_rtype && (funct7 == 7'b0000000);
    wire is_sub   = is_rtype && (funct7 == 7'b0100000);

    // Loads/Stores（只做 LW/SW）
    wire is_lw = (opcode == 7'b0000011) && (funct3 == 3'b010); // LW
    wire is_sw = (opcode == 7'b0100011) && (funct3 == 3'b010); // SW

    assign regwrite = is_addi | is_add | is_sub | is_lw;   // SW 不写回;
    assign alusrc   = is_addi | is_lw | is_sw;              // 这些用立即数
    assign alu_ctrl =
        is_sub  ? 4'b0001 : // SUB
        4'b0000;            // ADD / ADDI 默认

    assign memread  = is_lw;
    assign memwrite = is_sw;
    assign memtoreg = is_lw;                                // 只有 LW 从内存写回
endmodule
